/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package UTILITARIOS;

import java.awt.*;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.*;


/**
 *
 * @author Administrador
 */
public class UTextField extends JTextField{

    private static final long serialVersionUID = 1L;

	private JLabel content;
	private Popup response;
	private String toolTipStart;
	private String toolTipEnd;

	private int valueType;

	private boolean isMandatory;

	public static final int ANY_VALUE = -1;
	public static final int INT_VALUE = 1;
	public static final int DOUBLE_VALUE = 2;
	public static final int ONLY_CARACTERS_VALUE = 3;
	public static final int TIME_VALUE = 4;
	public static final int DATE_VALUE = 5;
	public static final int PHONE_FAX_VALUE = 6;
	public static final int MAIL_VALUE = 7;
	public static final int PASSWORD_VALUE = 8;

	private int MAX_CHAR_NUMBER = 100;

	private static final String[] MESSAGES = {"",
											"En este campo solo puede <br>"+Constantes.HTML_SPACES+" ingresar números enteros",
											"En este campo solo puede <br>"+Constantes.HTML_SPACES+" ingresar números reales",
											"En este campo solo puede <br>"+Constantes.HTML_SPACES+" ingresar carácteres sin números",
											"En este campo solo puede <br>"+Constantes.HTML_SPACES+" ingresar horas en formato [hh:mm:ss]",
											"En este campo solo puede <br>"+Constantes.HTML_SPACES+" ingresar fechas en formato [dd:mm:aa]",
											"En este campo solo puede <br>"+Constantes.HTML_SPACES+" ingresar numeros de telofono o fax",
											"En este campo solo puede <br>"+Constantes.HTML_SPACES+" ingresar direcciones de email",
											"En este campo solo puede <br>"+Constantes.HTML_SPACES+" ingresar una contraseña"
											};


	public UTextField() {
		MAX_CHAR_NUMBER = 100;
		buildComponents();
		addControl();
		setProperties();
	}

	private void setProperties() {
		setDisabledTextColor( Color.BLACK.brighter() );
		setSelectedTextColor(Color.BLUE);
		setSelectionColor(new Color(230, 247, 255));
	}

	public UTextField(int valueType) {
		this();
		setValueType(valueType);
	}

	public UTextField(int valueType, int maxCharNumber) {
		this();
		setValueType(valueType);
		this.MAX_CHAR_NUMBER = maxCharNumber;
	}

	private void buildComponents() {
		content= new JLabel();
		content.setFont( new Font("Tahoma",Font.PLAIN,11) );

		toolTipStart = "<html><body bgcolor=\"#FDFBE8\">"+Constantes.HTML_SPACES;
		toolTipEnd = Constantes.HTML_SPACES+"</body></html>";

		content.setText(toolTipStart + MESSAGES[valueType>0?valueType:0] + toolTipEnd);
	}

	public void setValueType( int valueType ){
		this.valueType = valueType;
		//tip.setTipText(toolTipStart + MESSAGES[valueType%MESSAGES.length] + toolTipEnd);
		content.setText(toolTipStart + MESSAGES[valueType>0?valueType:0] + toolTipEnd);
	}

	public boolean isMandatory() {
		return isMandatory;
	}
	/**
	 * Cambia el color de fondo del textfield, indicando si el campo es obligatorio o no.
	 * amarillo = obligatorio
	 * blanco = opcional
	 * @param isMandatory
	 */
	public void setMandatory(boolean isMandatory) {
		this.isMandatory = isMandatory;

		if( isMandatory )
			setBackground(new Color(255, 255, 230));
		else
			setBackground(Color.WHITE);
	}

	private void addControl() {
		addKeyListener((KeyListener) new KeyAdapter() {
			public void keyTyped(KeyEvent e) {

				if( (getSelectedText()!= null && getSelectedText().length()>0) ||
					(getRealText().length()<=MAX_CHAR_NUMBER || valueType != MAIL_VALUE ) )
				{
					//	En caso de que la tecla presionada sea una letra y el tipo del texto
					//	no sea diferente de un email, el texto se convierte a mayúculas.
					if( Character.isLetter(e.getKeyChar()) && valueType != MAIL_VALUE )
						e.setKeyChar( Character.toUpperCase(e.getKeyChar()) );

					if( response!= null )
						response.hide();

					if( valueType == INT_VALUE )
						addIntControl(e);
					else if( valueType == DOUBLE_VALUE )
						addDoubleControl(e);
					else if( valueType == ONLY_CARACTERS_VALUE )
						addCaractersControl(e);
					else if( valueType == TIME_VALUE )
						addHourControl(e);
					else if( valueType == DATE_VALUE )
						addDateControl(e);
					else if( valueType == PHONE_FAX_VALUE )
						addPhoneFaxValue(e);
				}
				else{
					e.consume();
					getToolkit().beep();
				}
			}

			@Override
			public void keyReleased(KeyEvent e) {
				if( valueType == TIME_VALUE && getText().length()==2 && e.getKeyChar() != KeyEvent.VK_BACK_SPACE )
					setText( getText()+":" );
                                        if( valueType == TIME_VALUE && getText().length()==5 && e.getKeyChar() != KeyEvent.VK_BACK_SPACE )
					setText( getText()+":" );
				else if( valueType == DATE_VALUE && (getText().length()==2 || getText().length()==5) && e.getKeyChar() != KeyEvent.VK_BACK_SPACE )
					setText( getText()+"-" );
			}
		});

		addFocusListener( new FocusAdapter(){
			public void focusGained(FocusEvent e) {
				selectAll();
			}
		});
	}

	@Override
	public String getText() {
		String text = super.getText();

		if( (valueType == INT_VALUE || valueType == DOUBLE_VALUE) && text.length()==0 )
			text = "0";

		return text;
	}

	public String getRealText(){
		return super.getText();
	}

	protected void addDateControl(KeyEvent e) {
		char c = e.getKeyChar();
		if ( !( Character.isDigit(c) || (c == KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE)
				|| (c == KeyEvent.VK_ENTER) ) || getText().length() >9 ) {
			getToolkit().beep();
			showToolTip();
			e.consume();
		}
	}

	protected void addHourControl(KeyEvent e) {
		char c = e.getKeyChar();
		if ( !( Character.isDigit(c) || (c == KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE)
				|| (c == KeyEvent.VK_ENTER) ) || getText().length() >7) {
			getToolkit().beep();
			showToolTip();
			e.consume();
		}
	}

	protected void addIntControl(KeyEvent e) {
		char c = e.getKeyChar();
		if ( !( Character.isDigit(c) || (c == KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE)
				|| (c == KeyEvent.VK_ENTER) )) {
			getToolkit().beep();
			showToolTip();
			e.consume();
		}
	}

	protected void addPhoneFaxValue(KeyEvent e) {
		char c = e.getKeyChar();
		if ( !( Character.isDigit(c) || !Character.isLetter(c) || (c == KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_SPACE) || (c == KeyEvent.VK_DELETE)
				|| (c == KeyEvent.VK_ENTER) )) {
			getToolkit().beep();
			showToolTip();
			e.consume();
		}
	}

	protected void addDoubleControl(KeyEvent e) {
		char c = e.getKeyChar();
		if (!( Character.isDigit(c) || (c == KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE) || (c == '.' && countDots() == 0)
				|| (c == KeyEvent.VK_ENTER) )) {
			getToolkit().beep();
			showToolTip();
			e.consume();
		}
	}

	private int countDots() {
		int counter = 0;

		String text = getText();

		for (int i = 0; i < text.length(); i++) {
			if( text.charAt(i) == '.' )
				counter++;
		}

		return counter;
	}

	protected void addCaractersControl(KeyEvent e) {
		char c = e.getKeyChar();
		if (!( Character.isLetter(c) || (c == KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE) || (c == '.' && countDots() == 0)
				|| (c == KeyEvent.VK_ENTER) || (c == KeyEvent.VK_SPACE) )) {
			getToolkit().beep();
			showToolTip();
			e.consume();
		}
	}

	protected void showToolTip() {
		response = PopupFactory.getSharedInstance().getPopup(this,content, getLocationOnScreen().x + 15,getLocationOnScreen().y + 20);

		response.show();
		Timer hideTimer = new Timer(4000, new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				response.hide();
			}
		});

		hideTimer.setRepeats(false);
		hideTimer.start();
		requestFocus();

	}

	public static void main(String[] args) {
		JFrame frame = new JFrame();
		frame.setSize(400,300);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setLayout(new FlowLayout());

		UTextField text = new UTextField(UTextField.DOUBLE_VALUE);
		text.setPreferredSize( new Dimension(290,20) );
		frame.add( text );

		frame.setVisible(true);
	}

}
